﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading;

namespace JinYuan.Helper
{
    /// <summary>
    /// 日志操作类
    /// </summary>
    public class LogHelper
    {
        private static object singleLock = new object();

        /// <summary>
        /// log日志文件路径
        /// </summary>
        public static string logFilePath = string.Empty;


        public static LogHelper _instance = null;
        public static LogHelper Instance
        {

            get
            {
                if (_instance == null)
                {
                    lock (singleLock)
                    {
                        if (_instance == null)
                        {
                            _instance = new LogHelper();
                        }
                    }
                }
                return _instance;
            }

        }




        /// <summary>
        /// 初始化
        /// </summary>
        /// <param name="configPath"></param>
        public void InitLog(string configPath)
        {
            logFilePath = configPath;
            if (!Directory.Exists(logFilePath))
            {
                Directory.CreateDirectory(logFilePath);
            }
            //if (!File.Exists(logFilePath))
            //{
            //    File.Create(logFilePath).Close();
            //}
        }


        /// <summary>
        /// 写日志文件数据库日志文件
        /// </summary>
        /// <param name="message">消息</param>  
        public void WriteError(string message)
        {

            AddLog(message, "Error");
        }

        public void WriteEX(Exception ex)
        {
            AddLog(ex.Message + "\r\n" + ex.InnerException + "\r\n" + ex.StackTrace + "\r\n" + ex.Source, "SysErrorLog");
        }

        public void WriteEX(string ErrorName, Exception ex)
        {
            AddLog(ErrorName + "\r\n" + ex.Message + "\r\n" + ex.InnerException + "\r\n" + ex.StackTrace + "\r\n" + ex.Source, "SysErrorLog");
        }
        /// <summary>
        /// 写日志文件数据库日志文件
        /// </summary>
        /// <param name="ex">消息</param> 
        /// <param name="direName">日志存储目录名称</param>
        public void WriteError(Exception ex, string direName)
        {
            AddLog(ex.Message + "\r\n" + ex.InnerException + "\r\n" + ex.StackTrace + "\r\n" + ex.Source, direName);
        }

        /// <summary>
        /// /
        /// </summary>
        /// <param name="message"></param>
        /// <param name="direName"></param>
        public void WriteError(string message, string direName)
        {
            AddLog(message, direName);
        }
        /// <summary>
        /// 写日志文件数据库日志文件
        /// </summary>
        /// <param name="message">消息</param>  
        public void WriteLog(string message)
        {

            AddLog(message, "Info");
        }
        /// <summary>
        /// 写日志文件数据库日志文件
        /// </summary>
        /// <param name="message">消息</param> 
        /// <param name="direName">日志存储目录名称</param>
        public void WriteLog(string message, string direName)
        {

            AddLog(message, direName);
        }

        /// <summary>
        /// 写日志文件数据库日志文件
        /// </summary>
        /// <param name="message">消息</param>
        /// <param name="direName">日志存储目录名称</param>
        private void AddLog(string message, string direName)
        {
            string fileLog = logFilePath;
            if (fileLog == "")
            {
                return;
            }
            try
            {
                var applicationName = direName;
                //从宿主配置文件中获取日志文件全路径
                //所有的接口日志文件放在一个目录下面，跟web站点的目录分开
                //日志文件一天放一个，按日期分开

                if (string.IsNullOrEmpty(applicationName))
                {
                    applicationName = "Log";
                }
                string logFullPath = fileLog + applicationName;

                if (!Directory.Exists(logFullPath))
                {
                    Directory.CreateDirectory(logFullPath);
                }
                //只保留30天的日志
                var deletePath = $@"{logFullPath}\{DateTime.Now.AddDays(-30):yyyyMMddHH}.txt";

                if (File.Exists(deletePath))
                {
                    File.Delete(deletePath);
                }

                logFullPath = $@"{logFullPath}\{DateTime.Now:yyyyMMddHH}.txt";
                if (!File.Exists(logFullPath))
                {
                    using (var fs = new FileStream(logFullPath, FileMode.Create, FileAccess.Write))
                    {
                        StreamWriter sw = new StreamWriter(fs);
                        sw.Close();
                        fs.Close();
                    }
                }

                using (StreamWriter writer = new StreamWriter(logFullPath, true))
                {
                    writer.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                    writer.WriteLine(message);
                    writer.WriteLine(Environment.NewLine);

                }

            }
            catch
            {
                // ignored
            }
        }

        /// <summary>
        /// 轴位置日志类
        /// </summary>
        public class PrintMotorLog
        {
            private static readonly Thread WriteThread;
            private static readonly Queue<string> MsgQueue;//先进先出集合
            public static readonly object FileLock;
            private static readonly string FilePath = "D:\\LOCAL\\轴位置修改记录(查看文件就复制到副本到桌面！！！)\\";
            static PrintMotorLog()
            {
                FileLock = new object();//文件锁

                WriteThread = new Thread(WriteMsg);
                MsgQueue = new Queue<string>();
                WriteThread.Start();
            }

            public static void LogInfo(string BegionTime, string MotorDescribe, string IndxDescribe, string FrontIndx, string NewIndx)
            {
                Monitor.Enter(MsgQueue);
                string strData = BegionTime + ","
                                  + MotorDescribe + ","
                                  + IndxDescribe + ","
                                  + FrontIndx + ","
                                  + NewIndx + ",";
                MsgQueue.Enqueue(strData);
                Monitor.Exit(MsgQueue);
            }
            private static void WriteMsg()
            {
                while (true)
                {
                    Thread.Sleep(10);
                    if (MsgQueue.Count > 0)
                    {
                        Monitor.Enter(MsgQueue);
                        string msg = MsgQueue.Dequeue();
                        Monitor.Exit(MsgQueue);
                        Monitor.Enter(FileLock);
                        if (!Directory.Exists(FilePath))
                        {
                            Directory.CreateDirectory(FilePath);
                        }
                        string strFilename = FilePath + "轴位置修改_" + System.DateTime.Now.ToString("yyyyMMdd") + ".csv";
                        //用默认编码和缓冲区大小，为指定的文件初始化 StreamWriter 类的一个新实例。 如果该文件存在，则可以将其覆盖或向其追加。 如果该文件不存在，则此构造函数将创建一个新文件。
                        try
                        {
                            if (!File.Exists(strFilename))
                            {
                                //文件标头 19
                                string strProInfoFileHead = @"日期时间,轴描述,位置描述,位置修改前,当前位置";
                                StreamWriter sw = new StreamWriter(strFilename, true, UnicodeEncoding.GetEncoding("GB2312"));
                                sw.WriteLine(strProInfoFileHead);
                                sw.Flush();
                                sw.Close();
                                sw.Dispose();
                            }
                            StreamWriter se = new StreamWriter(strFilename, true, UnicodeEncoding.GetEncoding("GB2312"));
                            se.WriteLine(msg);
                            se.Flush();
                            se.Close();
                            se.Dispose();
                        }
                        catch (Exception)
                        {


                        }
                        Monitor.Exit(FileLock);
                        if (GetFileSize(strFilename) > 1024 * 5)
                        {
                            CopyToBak(strFilename);
                        }
                    }
                }
            }
            private static long GetFileSize(string fileName)
            {
                long strRe = 0;
                if (File.Exists(fileName))
                {
                    Monitor.Enter(FileLock);
                    try
                    {
                        var myFs = new FileStream(fileName, FileMode.Open);
                        strRe = myFs.Length / 1024;
                        myFs.Close();
                        myFs.Dispose();
                    }
                    catch (Exception)
                    {


                    }
                    Monitor.Exit(FileLock);
                }
                return strRe;
            }

            private static void CopyToBak(string sFileName)
            {
                int fileCount = 0;
                string sBakName = "";
                Monitor.Enter(FileLock);
                try
                {
                    do
                    {
                        fileCount++;
                        sBakName = sFileName + "." + fileCount + ".BAK";
                    }
                    while (File.Exists(sBakName));
                    File.Copy(sFileName, sBakName);
                    File.Delete(sFileName);
                }
                catch (Exception)
                {


                }
                Monitor.Exit(FileLock);
            }
        }
    }
}
